package com.iwhalecloud.bss.kite.cucc.order.util;

import com.iwhalecloud.bss.kite.common.constant.TableConsts;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.util.SeqUtils;
import com.iwhalecloud.bss.kite.cucc.order.proxy.InstProxy;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.IInst;
import com.iwhalecloud.bss.kite.dataservice.entity.order.OrderItemChange;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.order.client.context.OrderContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 实例动态代理工具类
 */
public abstract class InstProxyUtils {

    /**
     * 创建代理实例
     * @param inst
     * @return
     */
    public static <T extends IInst> T createProxy(T inst) {
        if (Objects.isNull(inst)) {
            return inst;
        }

        if (AcceptUtils.isModifyInst(inst)) {
            // 修改的实例才需要代理
            InstProxy<T> instProxy = new InstProxy<>();
            return instProxy.createProxy(inst);
        }
        else {
            return inst;
        }
    }

    /**
     * 创建代理实例列表
     * @param insts
     * @return
     */
    public static <T extends IInst> List<T> createProxy(List<T> insts) {
        if (CollectionUtils.isEmpty(insts)) {
            return insts;
        }

        List<T> list = new ArrayList<>();
        for (T inst : insts) {
            list.add(createProxy(inst));
        }

        return list;
    }

    /**
     * 更新或生成新的属性变动信息
     * @param tableName
     * @param instId
     * @param fieldName
     * @param fieldValue
     * @param oldFieldValue
     */
    public static void createOrderItemChange(String tableName, String instId, String fieldName, String fieldValue,
        String oldFieldValue) {
        if (StringUtils.isAnyBlank(tableName, instId, fieldName) || KiteStringUtils.equals(fieldValue, oldFieldValue)) {
            return;
        }

        Map<String, List<OrderItemChange>> orderItemChangeMap = OrderContext.getOrderRequest().getOrderContainer()
            .getOrderItemChangeMap();
        orderItemChangeMap.forEach((orderItemId, orderItemChanges) -> {
            List<OrderItemChange> orderItemChangeList = listOrderItemChanges(orderItemChanges, tableName, instId);
            if (CollectionUtils.isNotEmpty(orderItemChangeList)) {
                // 如果实例原来就有属性变动信息，才会把新的属性变动信息补充进来
                OrderItemChange orderItemChange = getOrderItemChange(orderItemChangeList, tableName, instId, fieldName);
                if (Objects.nonNull(orderItemChange)) {
                    orderItemChange.setFieldValue(fieldValue);
                }
                else {
                    orderItemChange = KiteBeanUtils.transform(orderItemChangeList.get(0), OrderItemChange.class);
                    orderItemChange.setChgId(SeqUtils.getNext(TableConsts.OrderItemChange));
                    orderItemChange.setActionType(ActionType.M.name());
                    orderItemChange.setFieldName(fieldName);
                    orderItemChange.setFieldValue(fieldValue);
                    orderItemChange.setOldFieldValue(oldFieldValue);
                    orderItemChange.setHandleTime(new Date());
                    orderItemChange.setInstStateChg("XX");
                    orderItemChanges.add(orderItemChange);
                }

                return;
            }
        });
    }

    /**
     * 获取实例的变动信息列表
     * @param orderItemChanges
     * @param tableName
     * @param instId
     * @return
     */
    private static List<OrderItemChange> listOrderItemChanges(List<OrderItemChange> orderItemChanges, String tableName,
        String instId) {
        return orderItemChanges.stream().filter(orderItemChange -> {
            return Objects.equals(tableName, orderItemChange.getTableName())
                && Objects.equals(instId, orderItemChange.getInstId());
        }).collect(Collectors.toList());
    }

    /**
     * 获取实例属性的变动信息
     * @param orderItemChanges
     * @param tableName
     * @param instId
     * @param fieldName
     * @return
     */
    private static OrderItemChange getOrderItemChange(List<OrderItemChange> orderItemChanges, String tableName, String instId,
        String fieldName) {
        return orderItemChanges.stream().filter(orderItemChange -> {
            return Objects.equals(tableName, orderItemChange.getTableName())
                && Objects.equals(instId, orderItemChange.getInstId())
                && Objects.equals(fieldName, orderItemChange.getFieldName());
        }).findFirst().orElse(null);
    }
}
